﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.Diagnostics;
using System.Reflection;

namespace Client
{
    public abstract class ClientBaseService<T>
    {
        private DuplexChannelFactory<T> channelFactory;

        /// <summary>
        /// 采用通道工厂的方式生成客户端服务对象实例
        /// </summary>
        /// <param name="bind"></param>
        /// <param name="address"></param>
        protected string CreateClientInstanceByChannel(T t, params object[] parameter)
        {
            try
            {
                Type type = t.GetType();
                StackTrace st = new StackTrace(true);
                MethodInfo methodInfo = null;
                var listStackFrame = st.GetFrames().Where(x => type.GetMethod(x.GetMethod().Name) != null);
                if (listStackFrame != null)
                {
                    methodInfo = type.GetMethod(listStackFrame.First().GetMethod().Name);
                }

                if (methodInfo == null)
                {
                }
                ParameterInfo[] paramsInfo = methodInfo.GetParameters();
                object[] obj = new object[paramsInfo.Length];
                for (int i = 0; i < parameter.Length; i++)
                {
                    obj[i] = parameter[i];
                }
                string returnValue = (string)methodInfo.Invoke(t, obj);

                channelFactory.Close();
                return returnValue;
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
        }

        public virtual T GetChannelFactory(string Address)
        {
            NetTcpBinding bind = new NetTcpBinding() { MaxReceivedMessageSize = 2147483647 };
            bind.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()
            {
                MaxStringContentLength = 2147483647
            };
            bind.Security.Mode = SecurityMode.Message;

            string ServerIp = "127.0.0.1";

            string uri = string.Format("net.tcp://{0}:{1}/{2}", ServerIp, 9999, Address);
            EndpointAddress address = new EndpointAddress(uri);
            InstanceContext instanceContext = new InstanceContext(new PushCallback());

            channelFactory = new DuplexChannelFactory<T>(instanceContext, bind);
            channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;

            T proxyService = channelFactory.CreateChannel(address);
            return proxyService;
        }
    }
}